{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "<a href=\"https://colab.research.google.com/github/jeffheaton/app_deep_learning/blob/main/t81_558_class_06_3_alpaca_lora.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# T81-558: Applications of Deep Neural Networks\n",
        "**Module 6: ChatGPT and Large Language Models**\n",
        "* Instructor: [Jeff Heaton](https://sites.wustl.edu/jeffheaton/), McKelvey School of Engineering, [Washington University in St. Louis](https://engineering.wustl.edu/Programs/Pages/default.aspx)\n",
        "* For more information visit the [class website](https://sites.wustl.edu/jeffheaton/t81-558/)."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Module 6 Material\n",
        "\n",
        "* Part 6.1: Introduction to Transformers [[Video]](https://www.youtube.com/watch?v=mn6r5PYJcu0&list=PLjy4p-07OYzulelvJ5KVaT2pDlxivl_BN) [[Notebook]](t81_558_class_06_1_transformers.ipynb)\n",
        "* Part 6.2: Accessing the ChatGPT API [[Video]](https://www.youtube.com/watch?v=tcdscXl4o5w&list=PLjy4p-07OYzulelvJ5KVaT2pDlxivl_BN) [[Notebook]](t81_558_class_06_2_chat_gpt.ipynb)\n",
        "* **Part 6.3: Llama, Alpaca, and LORA** [[Video]](https://www.youtube.com/watch?v=oGQ3TQx1Qs8&list=PLjy4p-07OYzulelvJ5KVaT2pDlxivl_BN) [[Notebook]](t81_558_class_06_3_alpaca_lora.ipynb)\n",
        "* Part 6.4: Introduction to Embeddings [[Video]](https://www.youtube.com/watch?v=e6kcs9Uj_ps&list=PLjy4p-07OYzulelvJ5KVaT2pDlxivl_BN) [[Notebook]](t81_558_class_06_4_embedding.ipynb)\n",
        "* Part 6.5: Prompt Engineering [[Video]](https://www.youtube.com/watch?v=miTpIDR7k6c&list=PLjy4p-07OYzulelvJ5KVaT2pDlxivl_BN) [[Notebook]](t81_558_class_06_5_prompt_engineering.ipynb)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Google CoLab Instructions\n",
        "\n",
        "The following code ensures that Google CoLab is running the correct version of TensorFlow.\n",
        "  Running the following code will map your GDrive to ```/content/drive```."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "try:\n",
        "    from google.colab import drive\n",
        "    COLAB = True\n",
        "    print(\"Note: using Google CoLab\")\n",
        "except:\n",
        "    print(\"Note: not using Google CoLab\")\n",
        "    COLAB = False"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Part 6.3: Alpaca with Lora\n",
        "\n",
        "In the last section, we used ChatGPT via the OpenAI API. ChatGPT, and the models that it is based upon are closed. The only way to access these models is through an API. There are also open source LLMs, we will consider two of these.\n",
        "\n",
        "* LLaMA - A LLM released by Meta. LLaMA uses the transformer architecture, the standard architecture for language modeling since 2018.\n",
        "* Alpaca - A training recipe based on the LLaMA 7B model that uses the \"Self-Instruct\" method of instruction tuning to acquire capabilities comparable to the OpenAI GPT-3 series text-davinci-003 model at a modest cost. Released by Stanford University Institute for Human-Centered Artificial Intelligence (HAI) Center for Research on Foundation Models (CRFM)\n",
        "\n",
        "We can use a technology called LORA, that reduces the model's size, but at the expense of the quality of responses you receive. In this section, we will see that you can run Alpaca in a Google CoLab environment using LORA. This technology allows you to run the LLM on hardware you control directly.\n",
        "\n",
        "## Low-Rank Adaptation (LoRA)\n",
        "\n",
        "LoRA, or Low-Rank Adaptation, offers a novel approach to adapting large pre-trained language models for specific tasks or domains without requiring extensive fine-tuning of the entire model. Instead of adjusting all the parameters of a massive model like GPT-3 175B, LoRA introduces trainable rank decomposition matrices to each layer of the Transformer architecture. This strategy significantly reduces the number of trainable parameters for subsequent tasks. In the context of Google CoLab, where users might face GPU memory constraints, using LoRA is highly beneficial. For instance, by utilizing LoRA, the GPU memory requirement can be slashed three times compared to traditional fine-tuning processes. This allows running models like the Alpaca LLM inside Google CoLab without overburdening the platform's resources. Moreover, LoRA ensures equal or superior performance compared to fully fine-tuned models, making it an efficient and effective option for deploying models in environments like CoLab. Providing an integration package for PyTorch models further simplifies the process, making the application of LoRA in CoLab both feasible and advantageous.\n",
        "\n",
        "The following code installs the prerequisites for running [Alpaca-LoRA](https://github.com/tloen/alpaca-lora/).\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "X_pz8MuY84Qh",
        "outputId": "e43211f1-9f3b-4d62-8f8c-d4febc94acb3"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Requirement already satisfied: bitsandbytes in /usr/local/lib/python3.10/dist-packages (0.41.1)\n",
            "\u001b[33m  WARNING: Did not find branch or tag 'c3dc391', assuming revision or ref.\u001b[0m\u001b[33m\n",
            "\u001b[0m  Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n",
            "  Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n",
            "  Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n",
            "  Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n",
            "  Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n",
            "  Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n"
          ]
        }
      ],
      "source": [
        "!pip install bitsandbytes\n",
        "!pip install -q datasets loralib sentencepiece\n",
        "!pip install -q git+https://github.com/zphang/transformers@c3dc391\n",
        "!pip install -q git+https://github.com/huggingface/peft.git\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The following code loads the Alpaca LoRA pretrained model."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 87,
          "referenced_widgets": [
            "4d9f5115ce9e42d883e305f3c2f413ca",
            "53d04fe4ba7943f7939b81ee78fcf379",
            "a5efa5b338824bb992d3addb82e2059e",
            "c854e6582af14b229305f1d73d6dc165",
            "f469583fee52486e89b4bb93de417cf7",
            "9c71a59ea54f446dab98af4cee463247",
            "a761d37ae1f24d2e9aad0620e0442c71",
            "99652277696b40f4ab30c6bca4283c0c",
            "064e67b122ea44958542e1ae7c4e651f",
            "ee354db8ac354a33a3712a967cc1f0e8",
            "0f8df7f082d24043a8533f3ac74ca414"
          ]
        },
        "id": "VucO3HSMoJkz",
        "outputId": "eb5b7d5b-c2d6-4deb-8e7c-e5e09ce20ca5"
      },
      "outputs": [
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Overriding torch_dtype=None with `torch_dtype=torch.float16` due to requirements of `bitsandbytes` to enable model loading in mixed int8. Either pass torch_dtype=torch.float16 or don't pass this argument at all to remove this warning.\n"
          ]
        },
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "4d9f5115ce9e42d883e305f3c2f413ca",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "Loading checkpoint shards:   0%|          | 0/33 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "from peft import PeftModel\n",
        "from transformers import LLaMATokenizer, LLaMAForCausalLM, GenerationConfig\n",
        "\n",
        "tokenizer = LLaMATokenizer.from_pretrained(\"decapoda-research/llama-7b-hf\")\n",
        "model = LLaMAForCausalLM.from_pretrained(\n",
        "    \"decapoda-research/llama-7b-hf\",\n",
        "    load_in_8bit=True,\n",
        "    device_map=\"auto\",\n",
        ")\n",
        "model = PeftModel.from_pretrained(model, \"tloen/alpaca-lora-7b\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We provide a utility to build prompts. We allow either a singular prompt, or a prompt with instructions."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "w3_lzwcqermJ"
      },
      "outputs": [],
      "source": [
        "def generate_prompt(instruction, input=None):\n",
        "    if input:\n",
        "        return f\"\"\"Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.\n",
        "\n",
        "### Instruction:\n",
        "{instruction}\n",
        "\n",
        "### Input:\n",
        "{input}\n",
        "\n",
        "### Response:\"\"\"\n",
        "    else:\n",
        "        return f\"\"\"Below is an instruction that describes a task. Write a response that appropriately completes the request.\n",
        "\n",
        "### Instruction:\n",
        "{instruction}\n",
        "\n",
        "### Response:\"\"\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The following code provides an evaluate function that we will use to call Alpaca LoRA. "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "id": "Egh3beCVRpW5"
      },
      "outputs": [],
      "source": [
        "generation_config = GenerationConfig(\n",
        "    temperature=0.1,\n",
        "    top_p=0.75,\n",
        "    num_beams=4,\n",
        ")\n",
        "\n",
        "def evaluate(instruction, input=None):\n",
        "    prompt = generate_prompt(instruction, input)\n",
        "    inputs = tokenizer(prompt, return_tensors=\"pt\")\n",
        "    input_ids = inputs[\"input_ids\"].cuda()\n",
        "    generation_output = model.generate(\n",
        "        input_ids=input_ids,\n",
        "        generation_config=generation_config,\n",
        "        return_dict_in_generate=True,\n",
        "        output_scores=True,\n",
        "        max_new_tokens=256\n",
        "    )\n",
        "    for s in generation_output.sequences:\n",
        "        output = tokenizer.decode(s)\n",
        "        print(\"Response:\", output.split(\"### Response:\")[1].strip())"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We begin by testing Alpaca LoRA on a code generation question. "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "upOB2AQJSW9-",
        "outputId": "54102896-560c-4bc3-90db-f20d1f996c69"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Response: def fibonacci(n):\n",
            "    if n == 0:\n",
            "        return 0\n",
            "    elif n == 1:\n",
            "        return 1\n",
            "    else:\n",
            "        return fibonacci(n-1) + fibonacci(n-2)\n"
          ]
        }
      ],
      "source": [
        "evaluate(\"Write the python code to calculate the fibonacci sequence\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The LLM does not do as well on a YouTube video description. LoRA does decrease the quality of responses. This description is fairly generic and it does not seem that the LLM understands the distinction of these technologies mentioned."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "b_jilPoDhe9Z",
        "outputId": "0c424f6a-c1a9-49cc-cc0c-51ad3ebe9b78"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Response: In this video, you will learn how to use LORA to run an Alpaca LLM in CoLab. LORA is an open-source platform that allows users to easily create, deploy, and manage applications. Alpaca LLM is an open-source platform that allows users to easily create, deploy, and manage applications. In this video, you will learn how to use LORA to run an Alpaca LLM in CoLab.\n"
          ]
        }
      ],
      "source": [
        "evaluate(\"Write a YouTube description for a video that shows how to use LORA to run an Alpaca LLM in CoLab\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "It does seem to have basic geographical knowledge. "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "9n8xPScGiO_c",
        "outputId": "8818950b-8f2c-4105-d89e-ecc562caef78"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Response: The capital of the state of Florida is Tallahassee.\n"
          ]
        }
      ],
      "source": [
        "evaluate(\"What is the capital of the state of Florida\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "It does not seem to know who I am and appears to hallucinate a player from the Charlotte Hornets. "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "7KBKUKFpic0j",
        "outputId": "75202de2-9464-4898-f7ff-612cd5a2fe6d"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Response: Jeff Heaton is an American professional basketball player who currently plays for the Charlotte Hornets of the National Basketball Association (NBA).\n"
          ]
        }
      ],
      "source": [
        "evaluate(\"Who is Jeff Heaton?\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "It also fails to extract birthdays, in the same example that ChatGPT was successful. "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "B6xhN-70itXK",
        "outputId": "17b729c1-56e5-44de-c3ed-114d7c658544"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Response: NONE\n"
          ]
        }
      ],
      "source": [
        "INPUT = \"John was born on June 14, 1995, he was married on May 8, 2015.\"\n",
        "\n",
        "SYSTEM_PROMPT = \"You are to extract any birthdays from input, return the \" \\\n",
        "    \"date in the form 10-FEB-1990, or NONE if no birthday.\"\n",
        "\n",
        "evaluate(SYSTEM_PROMPT, INPUT)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Running LLaMA on a Local Computer\n",
        "\n",
        "It is possible to run LLaMA from your local computer, special installers have been created for both Windows and Mac. One such project is Ollama, which makes multiple installers available. Ollama also allows you to run variants of LLaMA of different sizes. \n",
        "\n",
        "* [Ollama Project](https://ollama.ai/)\n",
        "* [Ollama Project GitHub](https://github.com/jmorganca/ollama)\n",
        "\n",
        "Once installed, Ollama can be used from the command line. We will now see how effective \"llama2\" is at generating a YouTube video description. The \"lama2\" model contains 7B weights and requires 3.8GB of memory.\n",
        "\n",
        "```\n",
        "ollama run llama2\n",
        ">>> Write a YouTube description for a video that shows how to use LORA to run an Alpaca LLM in CoLab\n",
        " Title: How to Use LORA to Run an Alpaca LLM in CoLab\n",
        " hopefully, this video will help you learn how to use LORA to run an Alpaca LLM (Language Model) in Colab. \n",
        "\n",
        "In this tutorial, we will walk you through the steps of using LORA to train and deploy an Alpaca LLM in Google Colab. We will cover the following topics:\n",
        "\n",
        "1. Introduction to LORA and its capabilities\n",
        "2. How to install LORA in Colab\n",
        "3. Preparing the data for training\n",
        "4. Training the Alpaca LLM using LORA\n",
        "5. Deploying the Alpaca LLM in Colab\n",
        "6. Testing and evaluating the performance of the Alpaca LLM\n",
        "\n",
        "By the end of this video, you will have a good understanding of how to use LORA to run an Alpaca LLM in CoLab. You'll be able to leverage the power of LORA to train and deploy your own language models in Colab, and unlock new possibilities for natural language processing tasks. So, if you're ready to get started, let's dive in! \n",
        "\n",
        "Please note that this is just an example description, and you may need to adjust it based on the specific content of your video.\n",
        "```\n",
        "\n",
        "As you can see, the larger LLaMA 2 model produces a better result.\n",
        "\n",
        "## LLM Censoring\n",
        "\n",
        "Advanced LLMs often include safeguards that prevent them from producing malicious content. Sometimes, these safeguards will activate by mistake for something not particularly dangerous; consider this request for a spicy mayo recipe.\n",
        "\n",
        "```\n",
        "ollama run llama2\n",
        ">>> Write a recipe for dangerously spicy mayo\n",
        "I cannot provide a recipe for dangerously spicy mayo as it is not appropriate or safe to create or consume extremely spicy condiments.\n",
        "```\n",
        "\n",
        "Though regular LLaMA refuses this request, you can also use the uncensored version of LLaMA 2.\n",
        "\n",
        "\n",
        "```\n",
        "ollama run llama2-uncensored\n",
        ">>> Write a recipe for dangerously spicy mayo\n",
        "Ingredients:\n",
        "- 1 tablespoon of mayonnaise\n",
        "- 1 teaspoon of hot sauce (optional)\n",
        "- Pinch of cayenne pepper\n",
        "- Pinch of paprika\n",
        "- A dash of vinegar\n",
        "- Salt and pepper to taste\n",
        "```\n",
        "As you can see, the uncensored version produces a spicy recipe. You must be careful with the uncensored version of LLMs as they will write exactly what you tell them to. It is possible to create unethical or even illegal output in this way. You must be careful with uncensored LLMs.\n",
        "\n",
        "\n",
        "## Model Hallucination\n",
        "\n",
        "In the context of Language Models (LLMs) like OpenAI's GPT series, \"hallucination\" refers to the phenomenon where the model generates information that isn't based on its training data or is factually incorrect. Essentially, the model \"imagines\" details or facts that aren't grounded in reality or the input provided to it.\n",
        "\n",
        "Hallucinations in LLM outputs can be a concern, especially when users rely on the generated text for factual accuracy. The reasons for such hallucinations can be varied:\n",
        "\n",
        "Ambiguous Prompts: If a user's prompt is not clear or specific enough, the model might try to fill in the gaps with plausible-sounding, but inaccurate, information.\n",
        "\n",
        "Model Bias: Since models learn from vast amounts of data, they can sometimes reflect and amplify biases present in that data, leading to outputs that might not be entirely accurate.\n",
        "\n",
        "Overfitting or Memorization: While large LLMs are designed to generalize from their training data, there might be instances where they lean too heavily on specific patterns or snippets they've seen during training, leading to inaccuracies in novel scenarios.\n",
        "\n",
        "Inherent Model Limitations: No model is perfect, and even with the best design and vast amounts of data, there's always some probability that a model will make errors or generate incorrect outputs.\n",
        "\n",
        "To mitigate the risks of hallucinations, users are advised to cross-check information, especially in critical applications, and model developers continuously work on improving training methodologies and data sources to reduce such occurrences."
      ]
    }
  ],
  "metadata": {
    "accelerator": "GPU",
    "colab": {
      "gpuClass": "premium",
      "machine_shape": "hm",
      "provenance": []
    },
    "gpuClass": "premium",
    "kernelspec": {
      "display_name": "Python 3.9 (torch)",
      "language": "python",
      "name": "pytorch"
    },
    "language_info": {
      "name": "python",
      "version": "3.9.16"
    },
    "widgets": {
      "application/vnd.jupyter.widget-state+json": {
        "064e67b122ea44958542e1ae7c4e651f": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "ProgressStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "ProgressStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "bar_color": null,
            "description_width": ""
          }
        },
        "0f8df7f082d24043a8533f3ac74ca414": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "DescriptionStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "4d9f5115ce9e42d883e305f3c2f413ca": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "HBoxModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HBoxModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HBoxView",
            "box_style": "",
            "children": [
              "IPY_MODEL_53d04fe4ba7943f7939b81ee78fcf379",
              "IPY_MODEL_a5efa5b338824bb992d3addb82e2059e",
              "IPY_MODEL_c854e6582af14b229305f1d73d6dc165"
            ],
            "layout": "IPY_MODEL_f469583fee52486e89b4bb93de417cf7"
          }
        },
        "53d04fe4ba7943f7939b81ee78fcf379": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "HTMLModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_9c71a59ea54f446dab98af4cee463247",
            "placeholder": "​",
            "style": "IPY_MODEL_a761d37ae1f24d2e9aad0620e0442c71",
            "value": "Loading checkpoint shards: 100%"
          }
        },
        "99652277696b40f4ab30c6bca4283c0c": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "9c71a59ea54f446dab98af4cee463247": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "a5efa5b338824bb992d3addb82e2059e": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "FloatProgressModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "FloatProgressModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "ProgressView",
            "bar_style": "success",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_99652277696b40f4ab30c6bca4283c0c",
            "max": 33,
            "min": 0,
            "orientation": "horizontal",
            "style": "IPY_MODEL_064e67b122ea44958542e1ae7c4e651f",
            "value": 33
          }
        },
        "a761d37ae1f24d2e9aad0620e0442c71": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "DescriptionStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "c854e6582af14b229305f1d73d6dc165": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "HTMLModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_ee354db8ac354a33a3712a967cc1f0e8",
            "placeholder": "​",
            "style": "IPY_MODEL_0f8df7f082d24043a8533f3ac74ca414",
            "value": " 33/33 [00:18&lt;00:00,  1.81it/s]"
          }
        },
        "ee354db8ac354a33a3712a967cc1f0e8": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "f469583fee52486e89b4bb93de417cf7": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        }
      }
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
